// Copyright (c) 2024 CHANGLEI. All rights reserved.

import 'package:charts_grasp/src/chart/chart_series/xy_data_series.dart';
import 'package:charts_grasp/src/chart/series_painter/error_bar_painter.dart';
import 'package:charts_grasp/src/chart/utils/enum.dart';
import 'package:charts_grasp/src/common/series/chart_series.dart';
import 'package:charts_grasp/src/common/utils/enum.dart';
import 'package:charts_grasp/src/common/utils/typedef.dart';

class ErrorBarSeries<T, D> extends XyDataSeries<T, D> {
  ErrorBarSeries({
    super.key,
    super.onCreateRenderer,
    required super.dataSource,
    required ChartValueMapper<T, D> super.xValueMapper,
    required ChartValueMapper<T, num> super.yValueMapper,
    super.sortFieldValueMapper,
    super.pointColorMapper,
    super.sortingOrder,
    super.xAxisName,
    super.yAxisName,
    super.name,
    super.color,
    double? width,
    super.emptyPointSettings,
    super.isVisible,
    super.animationDuration,
    super.opacity,
    double super.animationDelay = 1500,
    super.dashArray,
    super.onRendererCreated,
    super.legendItemText,
    bool super.isVisibleInLegend = false,
    LegendIconType super.legendIconType = LegendIconType.verticalLine,
    this.type = ErrorBarType.fixed,
    this.direction = Direction.both,
    this.mode = RenderingMode.vertical,
    this.verticalErrorValue = 3,
    this.horizontalErrorValue = 1,
    this.verticalPositiveErrorValue = 3,
    this.horizontalPositiveErrorValue = 1,
    this.verticalNegativeErrorValue = 3,
    this.horizontalNegativeErrorValue = 1,
    this.capLength = 10,
    this.onRenderDetailsUpdate,
    super.onCreateShader,
  }) : super(
          width: width ?? 2,
        );

  final ErrorBarType? type;

  final Direction? direction;

  final RenderingMode? mode;

  final double? verticalErrorValue;

  final double? horizontalErrorValue;

  final double? verticalPositiveErrorValue;

  final double? horizontalPositiveErrorValue;

  final double? verticalNegativeErrorValue;

  final double? horizontalNegativeErrorValue;

  final double? capLength;

  final ChartErrorBarRenderCallback? onRenderDetailsUpdate;

  ErrorBarSeriesRenderer createRenderer(ChartSeries<T, D> series) {
    ErrorBarSeriesRenderer seriesRenderer;
    if (onCreateRenderer != null) {
      seriesRenderer = onCreateRenderer!(series) as ErrorBarSeriesRenderer;
      return seriesRenderer;
    }
    return ErrorBarSeriesRenderer();
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    if (other.runtimeType != runtimeType) {
      return false;
    }

    return other is ErrorBarSeries &&
        other.key == key &&
        other.onCreateRenderer == onCreateRenderer &&
        other.dataSource == dataSource &&
        other.xValueMapper == xValueMapper &&
        other.yValueMapper == yValueMapper &&
        other.sortFieldValueMapper == sortFieldValueMapper &&
        other.pointColorMapper == pointColorMapper &&
        other.sortingOrder == sortingOrder &&
        other.xAxisName == xAxisName &&
        other.yAxisName == yAxisName &&
        other.name == name &&
        other.color == color &&
        other.width == width &&
        other.emptyPointSettings == emptyPointSettings &&
        other.isVisible == isVisible &&
        other.dashArray == dashArray &&
        other.animationDuration == animationDuration &&
        other.isVisibleInLegend == isVisibleInLegend &&
        other.legendIconType == legendIconType &&
        other.legendItemText == legendItemText &&
        other.opacity == opacity &&
        other.animationDelay == animationDelay &&
        other.onRendererCreated == onRendererCreated &&
        other.type == type &&
        other.direction == direction &&
        other.mode == mode &&
        other.verticalErrorValue == verticalErrorValue &&
        other.horizontalErrorValue == horizontalErrorValue &&
        other.verticalPositiveErrorValue == verticalPositiveErrorValue &&
        other.horizontalPositiveErrorValue == horizontalPositiveErrorValue &&
        other.verticalNegativeErrorValue == verticalNegativeErrorValue &&
        other.horizontalNegativeErrorValue == horizontalNegativeErrorValue &&
        other.capLength == capLength &&
        other.onCreateShader == onCreateShader &&
        other.onRenderDetailsUpdate == onRenderDetailsUpdate;
  }

  @override
  int get hashCode {
    final List<Object?> values = <Object?>[
      key,
      onCreateRenderer,
      dataSource,
      xValueMapper,
      yValueMapper,
      sortFieldValueMapper,
      pointColorMapper,
      sortingOrder,
      xAxisName,
      yAxisName,
      name,
      color,
      width,
      emptyPointSettings,
      isVisible,
      dashArray,
      animationDuration,
      isVisibleInLegend,
      legendIconType,
      legendItemText,
      opacity,
      animationDelay,
      onRendererCreated,
      type,
      direction,
      mode,
      verticalErrorValue,
      horizontalErrorValue,
      verticalPositiveErrorValue,
      verticalNegativeErrorValue,
      horizontalPositiveErrorValue,
      horizontalNegativeErrorValue,
      capLength,
      onRenderDetailsUpdate,
    ];
    return Object.hashAll(values);
  }
}

class ChartErrorValues {
  ChartErrorValues({this.errorX, this.errorY, this.customNegativeX, this.customNegativeY});

  num? errorX;

  num? errorY;

  num? customNegativeX;

  num? customNegativeY;
}

class ErrorBarMean {
  ErrorBarMean({this.verticalSquareRoot, this.horizontalSquareRoot, this.verticalMean, this.horizontalMean});

  final num? verticalSquareRoot;

  final num? horizontalSquareRoot;

  final num? verticalMean;

  final num? horizontalMean;
}
